package com.fangyi.yunmusic.interceptor;

import com.fangyi.yunmusic.exception.CacheEmptyException;
import com.fangyi.yunmusic.utils.JsonResult;
import com.fangyi.yunmusic.utils.JsonUtils;
import com.google.common.cache.Cache;
import com.google.common.cache.LoadingCache;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

public class LoginInterceptor extends BaseInterceptor{

    @Autowired
    @Qualifier("userTokenCache")
    private LoadingCache<String, String> userTokenCache;

    /**
     * 拦截请求，在controller调用之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 0. 若请求不是POST，放行
        if (!request.getMethod().equals("POST")) {
            return true;
        }
        // 1. 从请求头中得到userId，userToken
        String userId = request.getHeader("userId");
        String userToken = request.getHeader("userToken");
        // 2. 若userId, userToken不存在，不放行
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(userToken)) {
            returnErrorResponse(response, JsonResult.errorTokenMsg("id或token为空"));
            return false;
        }
        // 3. 在缓存中查询 请求中的userId 是否有对应的userToken
        //    3.1 查询userToken
        String cacheUserToken = null;
        try {
            cacheUserToken = userTokenCache.get(userId);
        } catch (Exception e) {
            // 缓存为空
//            e.printStackTrace();
        }

        //    3.2 若缓存中userId没有对应的userToken，则用户未登录，不放行
        if (cacheUserToken == null) {
            returnErrorResponse(response, JsonResult.errorTokenMsg("请登录..."));
            return false;
        }
        //    3.3 若缓存中userId有对应的userToken，但与请求中的userToken不同，则可能是用户已在他处登录，需要重新登录以挤掉之前的登录信息，故不放行
        if (!cacheUserToken.equals(userToken)) {
            returnErrorResponse(response, JsonResult.errorTokenMsg("账号被挤出..."));
            return false;
        }
        //    3.4 若有，则用户已登录，可放行
        return true;
    }

    /**
     * 请求controller之后，渲染视图之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 视图渲染之后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
